package com.xinzhidi.web.task;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.xinzhidi.common.constant.AgreementConstants;
import com.xinzhidi.common.utils.DateUtils;
import com.xinzhidi.web.alarmSetting.domain.AlarmSetting;
import com.xinzhidi.web.alarmSetting.service.AlarmSettingService;
import com.xinzhidi.web.dtuusr.domain.DtuUsr;
import com.xinzhidi.web.dtuusr.service.DtuUsrService;
import com.xinzhidi.web.equipment.domain.Equipment;
import com.xinzhidi.web.equipment.domain.vo.EquipmentInfoVo;
import com.xinzhidi.web.equipment.service.EquipmentService;
import com.xinzhidi.web.equipmentAlarm.domain.EquipmentAlarm;
import com.xinzhidi.web.equipmentAlarm.service.EquipmentAlarmService;
import com.xinzhidi.web.netty.entity.DeviceInstruction;
import com.xinzhidi.web.netty.server.SocketHandler;
import com.xinzhidi.web.netty.server.WsServer;
import com.xinzhidi.web.netty.service.DeviceInstructionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * 消息下发
 *
 * @author cx
 */
@Component("sendInstruction")
public class MessageTask {

    @Autowired
    private DeviceInstructionService deviceInstructionService;

    @Autowired
    private DtuUsrService dtuUsrService;

    @Autowired
    private AlarmSettingService alarmSettingService;

    @Autowired
    private EquipmentService equipmentService;

    @Autowired
    private EquipmentAlarmService equipmentAlarmService;

    public void ryNoParams() {
        this.sendMessage();
    }

    public int num = 1;

    /**
     * 下发消息
     **/
    private String sendMessage() {
        Integer port = WsServer.port;
        System.out.println("-------------下发消息的端口为：" + port);
        List<DeviceInstruction> list = deviceInstructionService.getDeviceMessage(port);
        if (CollectionUtils.isEmpty(list)) {
            return null;
        }
        System.out.println("待下发消息数量为：" + list.size() + "条");
        for (DeviceInstruction deviceInstruction : list) {
            System.out.println("下发消息的id为：" + deviceInstruction.getId());
            DtuUsr dtuUsr = dtuUsrService.getOne(new LambdaQueryWrapper<DtuUsr>(DtuUsr.class)
                    .eq(DtuUsr::getId, deviceInstruction.getDtuId())
                    .eq(DtuUsr::getStatus, 0)
            );

            if (dtuUsr == null) {
                deviceInstruction.setSendFailTime(DateUtils.getNowDate());
                deviceInstruction.setStatus(AgreementConstants.InstructSendingState.SEND_FAILURE);
                deviceInstructionService.updateById(deviceInstruction);
                continue;
            }
            Equipment equipment;
            LambdaQueryWrapper<Equipment> equipmentWrapper = Wrappers.lambdaQuery();
            equipmentWrapper.eq(Equipment::getAddress, deviceInstruction.getAddress())
                    .eq(Equipment::getDtuId, deviceInstruction.getDtuId())
                    .eq(Equipment::getDelFlag, AgreementConstants.DEL_FLAG_NO);
            equipment = equipmentService.getOne(equipmentWrapper);
            if (equipment == null) {
                deviceInstruction.setStatus(AgreementConstants.InstructSendingState.SEND_FAILURE);
                deviceInstructionService.updateById(deviceInstruction);
                continue;
            }

            //如果状态为0，则将状态修改为1，且发送数据

            if (deviceInstruction.getStatus().equals(AgreementConstants.InstructSendingState.WAIT_TO_SENT)) {
                deviceInstruction.setSendTimes(deviceInstruction.getSendTimes() + 1);
                deviceInstruction.setStatus(AgreementConstants.InstructSendingState.BEEN_SENT);
            } else if (deviceInstruction.getStatus().equals(AgreementConstants.InstructSendingState.BEEN_SENT)) {
                if (deviceInstruction.getSendTimes() >= deviceInstruction.getExceedTimes()) {
                    //先设置设备状态为离线
                    equipmentService.updateById(equipment);
                    deviceInstruction.setStatus(AgreementConstants.InstructSendingState.SEND_FAILURE);
                    deviceInstructionService.updateById(deviceInstruction);
                        System.out.println("=======设备id为【" + equipment.getAddress() + "】的指令接收回复失败");
                    this.saveMessageException(deviceInstruction);
                    continue;
                } else {
                    deviceInstruction.setSendTimes(deviceInstruction.getSendTimes() + 1);
                }
            }

            System.out.println("状态为：" + deviceInstruction.getStatus() + ",总次数为：" + deviceInstruction.getExceedTimes() + ",实际发送次数为：" + deviceInstruction.getSendTimes());

            //status为消息下发的状态  1：下发成功  -1：下发失败
            Integer status = SocketHandler.sendMessage(dtuUsr.getRegisterPackage(), deviceInstruction.getInstructionSet());
            deviceInstruction.setStatus(AgreementConstants.InstructSendingState.BEEN_SENT);
            if (status == -1) {
                if (deviceInstruction.getSendTimes() >= deviceInstruction.getExceedTimes()) {
                    deviceInstruction.setStatus(AgreementConstants.InstructSendingState.SEND_FAILURE);
                    deviceInstruction.setSendFailTime(DateUtils.getNowDate());
                    System.out.println("=======id为【" + deviceInstruction.getId() + "】的指令接收回复失败");
                    equipment.setStatus(2);
                    equipmentService.updateById(equipment);
                }
            }

            deviceInstructionService.updateById(deviceInstruction);

        }
        return null;
    }

    /**
     * 保存通讯异常
     */
    public void saveMessageException(DeviceInstruction deviceInstruction) {

        EquipmentInfoVo equipment = equipmentService.getEquipmentInfoVo(deviceInstruction.getDtuId(), deviceInstruction.getAddress());
        if (equipment == null) {
            return;
        }

        EquipmentAlarm equipmentAlarm;
        LambdaQueryWrapper<EquipmentAlarm> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(EquipmentAlarm::getEquipmentId, equipment.getId())
                .eq(EquipmentAlarm::getStatus, 0)
                .like(EquipmentAlarm::getRemark, "【" + equipment.getAddress() + "】通讯异常");

        AlarmSetting alarmSetting;
        LambdaQueryWrapper<AlarmSetting> alarmSettingWrapper = Wrappers.lambdaQuery();

        alarmSettingWrapper.eq(AlarmSetting::getAlarmType, AgreementConstants.ExceptionType.COMMUNICATION_EXCEPTION)
                .eq(AlarmSetting::getEquipmentType, equipment.getProtocolType())
                .eq(AlarmSetting::getDelFlag, AgreementConstants.DEL_FLAG_NO);

        alarmSetting = alarmSettingService.getOne(alarmSettingWrapper);
        if(alarmSetting == null){
            return;
        }
        queryWrapper.eq(EquipmentAlarm::getAlarmSettingId, alarmSetting.getId());
        equipmentAlarm = equipmentAlarmService.getOne(queryWrapper);
        if (equipmentAlarm == null) {
            equipmentAlarm = new EquipmentAlarm();
            equipmentAlarm.setPlotId(equipment.getLotId());
            equipmentAlarm.setBuildId(equipment.getBuildId());
            equipmentAlarm.setUnitId(equipment.getUnitId());
            equipmentAlarm.setHouseholdId(equipment.getHouseholdId());
            equipmentAlarm.setEquipmentId(equipment.getId());
            equipmentAlarm.setAlarmSettingId(alarmSetting.getId());
            equipmentAlarm.setHideOrPush(Integer.parseInt(alarmSetting.getPushStatus()));
            equipmentAlarm.setPushNum(alarmSetting.getPushInterval());
        } else {
            equipmentAlarm.setUpdateTime(DateUtils.getNowDate());
        }
        equipmentAlarm.setRemark(equipment.getName() + " 设备" + "【" + equipment.getAddress() + "】通讯异常");
        equipmentAlarmService.saveOrUpdate(equipmentAlarm);
    }

}
